package com.rambo.baselib.msgbus;

import com.rambo.baselib.util.ToastUtil;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.event.commonevent.CommonEventData;
import ohos.event.commonevent.CommonEventManager;
import ohos.event.commonevent.CommonEventPublishInfo;
import ohos.event.commonevent.CommonEventSubscriber;
import ohos.rpc.RemoteException;
import ohos.security.SystemPermission;

import java.io.Serializable;

/***********************************************************************
 * <p>@description: 公共事件通知，订阅
 * https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-notification-fwk-common-event-0000000000029871
 * <p>@author: rambo
 * <p>@version: 1.0.0
 * <p>@created on: 2022/1/19 16:58
 **********************************************************************/
public class EventBus {
    public static String DATA_KEY = "data_key";
    public static String TYPE_KEY = "type_key";
    public static String EVENT_ACTION = "event_action";
    static volatile EventBus eventBus;

    private EventBus() {

    }

    public static EventBus getEventBus() {
        if (eventBus == null) {
            synchronized (EventBus.class) {
                if (eventBus == null) {
                    eventBus = new EventBus();
                }
            }
        }
        return eventBus;
    }

    /**
     * 发布无序事件
     *
     * @param eventData
     */
    public void publish(CommonEventData eventData) {
        try {
            CommonEventManager.publishCommonEvent(eventData);
        } catch (RemoteException e) {
            e.printStackTrace();
            ToastUtil.toast("发送失败：" + e.getMessage());
        }
    }

    /**
     * @param type 事件类型
     * @param data 事件数据（不可以传递大容量数据）
     * @param <T>
     */
    public <T extends Serializable> void publish(int type, T data) {
        Intent intent = new Intent();
        //action 不能未空
        Operation operation = new Intent.OperationBuilder()
                .withAction(EVENT_ACTION)
                .build();
        intent.setOperation(operation);
        if (data != null) {
            intent.setParam(DATA_KEY, data);
        }
        intent.setParam(TYPE_KEY, type);
        CommonEventData eventData = new CommonEventData(intent);
        try {
            CommonEventManager.publishCommonEvent(eventData);
        } catch (RemoteException e) {
            e.printStackTrace();
            ToastUtil.toast("发送失败：" + e.getMessage());
        }
    }

    /**
     * 发送有序的公共事件
     *
     * @param type 事件类型
     * @param data 事件数据（不可以传递大容量数据）
     * @param <T>
     */

    public <T extends Serializable> void publishOrder(int type, T data, CommonEventSubscriber resultSubscriber) {
        Intent intent = new Intent();
        //action 不能未空
        Operation operation = new Intent.OperationBuilder()
                .withAction(EVENT_ACTION)
                .build();
        intent.setOperation(operation);
        if (data != null) {
            intent.setParam(DATA_KEY, data);
        }
        intent.setParam(TYPE_KEY, type);
        CommonEventPublishInfo publishInfo = new CommonEventPublishInfo();
        publishInfo.setOrdered(true);
        CommonEventData eventData = new CommonEventData(intent);
        try {
            CommonEventManager.publishCommonEvent(eventData, publishInfo, resultSubscriber);
        } catch (RemoteException e) {
            e.printStackTrace();
            ToastUtil.toast("发送失败：" + e.getMessage());
        }
    }

    /**
     * 订阅无序通知
     *
     * @param subscriber
     */
    public void subscriber(CommonEventSubscriber subscriber) {
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            e.printStackTrace();
            ToastUtil.toast("订阅失败：" + e.getMessage());
        }
    }

    /**
     * 取消订阅
     *
     * @param subscriber
     */
    public void unSubscriber(CommonEventSubscriber subscriber) {
        if (subscriber != null) {
            try {
                CommonEventManager.unsubscribeCommonEvent(subscriber);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

}
